﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Htse.Blue.Data;
using Htse.Blue.Models;
using Htse.Blue.Logic.Validation;
using System.Linq.Dynamic;

namespace Htse.Blue.Logic
{
	public abstract class ServiceBase<T, K, R> : IService<T, K, R>
		where T : class
		where K : struct
		where R : IRepository<T, K>
	{
		protected R repository;
		private IValidationDictionary<T> validationDictionary;

		protected IValidationDictionary<T> ValidationDictionary
		{
			get
			{
				return validationDictionary;
			}
		}

		public ServiceBase(IValidationDictionary<T> validationDictionary, R repository)
		{
			this.validationDictionary = validationDictionary;
			this.repository = repository;
		}

		#region IService<T,K,R> Members

		public virtual IQueryable<T> GetAll()
		{
			return repository.GetAll();
		}

		public virtual PagedList<T> GetAll(int? page, int pageSize, string sortingParameter)
		{
			if (string.IsNullOrEmpty(sortingParameter))
			{
				return repository.GetAll().ToPagedList(page, pageSize);
			}
			else
			{
				return repository.GetAll().OrderBy(sortingParameter).ToPagedList(page, pageSize, sortingParameter);
			}
		}

		public virtual T GetById(K id)
		{
			return repository.GetById(id);
		}

		public virtual bool Create(T entityToCreate)
		{
			if (!ValidateOnCreate(entityToCreate))
			{
				return false;
			}

			repository.Create(entityToCreate);

			return true;
		}

		public virtual bool Update(T entityToUpdate)
		{
			if (!ValidateOnUpdate(entityToUpdate))
			{
				return false;
			}

			repository.SaveOrUpdate(entityToUpdate);

			return true;
		}

		public virtual bool Delete(T entityToDelete)
		{
			repository.Delete(entityToDelete);

			return true;
		}

		#endregion

		protected virtual void ValidateAlways(
			T entityToValidate,
			IValidationDictionary<T> validationDictionary)
		{
		}

		protected virtual void ValidateOnlyOnCreate(
			T entityToValidate,
			IValidationDictionary<T> validationDictionary)
		{
		}

		protected virtual void ValidateOnlyOnUpdate(
			T entityToValidate,
			IValidationDictionary<T> validationDictionary)
		{
		}

		private bool ValidateOnCreate(T entityToCreate)
		{
			ValidateAlways(entityToCreate, validationDictionary);

			ValidateOnlyOnCreate(entityToCreate, validationDictionary);

			return validationDictionary.IsValid;
		}

		private bool ValidateOnUpdate(T entityToUpdate)
		{
			ValidateAlways(entityToUpdate, validationDictionary);

			ValidateOnlyOnUpdate(entityToUpdate, validationDictionary);

			return validationDictionary.IsValid;
		}
	}
}
